//
//  UIView+DFExtension.m
//  Pods
//
//  Created by rujia chen on 2017/04/02.
//
//

#import "UIView+DFExtension.h"
#import "NSObject+DFSwizzle.h"
#import "DFKitMarco.h"
#import "UIColor+DFExtension.h"
#if TARGET_OS_IPHONE
#import <objc/runtime.h>
#import <objc/message.h>
#else
#import <objc/objc-class.h>
#endif
#import "Masonry.h"

typedef BOOL(^PointTouchBlock)(UIView *view, CGPoint point, UIEvent *event);

const char *kPropertyIntrinsicContentSizeBlock;

const char *kPropertyPointTouchBlock;

@implementation UIView (DFExtension)

+ (void)load {
    [self df_swizzleMethod:@selector(intrinsicContentSize) withMethod:@selector(df_intrinsicContentSize) error:nil];
    [self df_swizzleMethod:@selector(pointInside:withEvent:) withMethod:@selector(df_pointInside:withEvent:) error:nil];
}

- (UIViewController *)df_viewController {
    for (UIView *view = self; view; view = view.superview) {
        UIResponder *nextResponder = [view nextResponder];
        if ([nextResponder isKindOfClass:[UIViewController class]]) {
            return (UIViewController *)nextResponder;
        }
    }
    
    return nil;
}

- (void)df_setIntrinsicContentSizeBlock:(DFIntrinsicContentSizeBlock)block {
    objc_setAssociatedObject(self, &kPropertyIntrinsicContentSizeBlock, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (void)df_expandTouchAreaByInsets:(UIEdgeInsets)insets {
    [self df_setPointTouchBlock:^BOOL(UIView *view, CGPoint point, UIEvent *event) {
        if (CGRectContainsPoint(UIEdgeInsetsInsetRect(view.bounds, insets), point)) {
            return YES;
        }else {
            return NO;
        }
    }];
}

- (void)df_setPointTouchBlock:(PointTouchBlock)block {
    objc_setAssociatedObject(self, &kPropertyPointTouchBlock, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (void)df_addBorder {
    [self df_addBorderWithColor:[UIColor df_colorByHex:@"CAC8CD"]];
}

- (void)df_addBorderWithColor:(UIColor *)color {
    [self df_addBorderWithColor:color lineWidth:DF_ONE_PIXEL];
}

- (void)df_addBorderWithColor:(UIColor *)color lineWidth:(CGFloat)lineWidth {
    self.layer.borderWidth = lineWidth;
    self.layer.borderColor = color.CGColor;
}

- (void)df_removeBorder {
    self.layer.borderWidth = 0;
}

+ (instancetype)lineWithDirection:(DFLineDirection)lineDirection {
    return [self lineWithDirection:lineDirection color:[UIColor blackColor]];
}

+ (instancetype)lineWithDirection:(DFLineDirection)lineDirection color:(UIColor *)color {
    UIView *line = DFMakeViewWithBackgroundColor(color);
    switch (lineDirection) {
        case DFLineDirectionVertical:
            [line df_setIntrinsicContentSizeBlock:^CGSize(UIView *view) {
                return CGSizeMake(DF_ONE_PIXEL, UIViewNoIntrinsicMetric);
            }];
            [line setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
            break;
        case DFLineDirectionHorizontal:
            [line df_setIntrinsicContentSizeBlock:^CGSize(UIView *view) {
                return CGSizeMake(UIViewNoIntrinsicMetric, DF_ONE_PIXEL);
            }];
            [line setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
            break;
        default:
            break;
    }
    return line;
}

#pragma mark - swizzled implementation

- (CGSize)df_intrinsicContentSize {
    DFIntrinsicContentSizeBlock block = objc_getAssociatedObject(self, &kPropertyIntrinsicContentSizeBlock);
    if (!block) {
        return [self df_intrinsicContentSize];
    } else {
        return block(self);
    }
}

- (BOOL)df_pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    PointTouchBlock block = objc_getAssociatedObject(self, &kPropertyPointTouchBlock);
    if (!block) {
        return [self df_pointInside:point withEvent:event];
    }else {
        return block(self, point, event);
    }
}

@end

@implementation UIView (DFHud)

- (void)df_setHud:(UIView *)df_hud {
    if (self.df_hud) {
        [self.df_hud removeFromSuperview];
    }
    objc_setAssociatedObject(self, @selector(df_hud), df_hud, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self addSubview:self.df_hud];
    [self.df_hud mas_makeConstraints:^(MASConstraintMaker *make) {
        make.center.equalTo(self).centerOffset(self.df_hudCenterOffset);
    }];
    
}

- (UIView *)df_hud {
    return objc_getAssociatedObject(self, _cmd);
}

- (void)df_setHudCenterOffset:(CGPoint)df_hudCenterOffset {
    objc_setAssociatedObject(self, @selector(df_hudCenterOffset), [NSValue valueWithCGPoint:df_hudCenterOffset], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    if (self.df_hud.superview) {
        [self.df_hud mas_updateConstraints:^(MASConstraintMaker *make) {
            make.center.equalTo(self).centerOffset(self.df_hudCenterOffset);
        }];
    }
}

- (CGPoint)df_hudCenterOffset {
    return [objc_getAssociatedObject(self, _cmd) CGPointValue];
}

@end
